--- /dev/null
+#ifndef __GTK_ARRAY_IMPL_PRIVATE_H__
+#define __GTK_ARRAY_IMPL_PRIVATE_H__
+
+
+/* This is a dumbed-down GPtrArray, which takes some stack
+ * space to use. When using this, the general case should always
+ * be that the number of elements is lower than reversed_size.
+ * The GPtrArray should only be used in extreme cases.
+ */
+
+typedef struct
+{
+ guint reserved_size;
+ guint len;
+ void **stack_space;
+ GPtrArray *ptr_array;
+
+} GtkArray;
+
+
+static inline void
+gtk_array_init (GtkArray *self,
+ void **stack_space,
+ guint reserved_size)
+{
+ self->reserved_size = reserved_size;
+ self->len = 0;
+ self->stack_space = stack_space;
+ self->ptr_array = NULL;
+}
+
+static inline void *
+gtk_array_index (GtkArray *self,
+ guint index)
+{
+ g_assert (index < self->len);
+
+ if (G_LIKELY (!self->ptr_array))
+ return self->stack_space[index];
+
+ return g_ptr_array_index (self->ptr_array, index);
+}
+
+static inline void
+gtk_array_add (GtkArray *self,
+ void *element)
+{
+ if (G_LIKELY (self->len < self->reserved_size))
+ {
+ self->stack_space[self->len] = element;
+ self->len++;
+ return;
+ }
+
+ /* Need to fall back to the GPtrArray */
+ if (G_UNLIKELY (!self->ptr_array))
+ {
+ guint i;
+
+ self->ptr_array = g_ptr_array_new_full (self->reserved_size, NULL);
+
+ /* Copy elements from stack space to GPtrArray */
+ for (i = 0; i < self->len; i++)
+ g_ptr_array_add (self->ptr_array, self->stack_space[i]);
+ }
+
+ g_ptr_array_add (self->ptr_array, element);
+ self->len++; /* We still count self->len */
+}
+
+static inline void
+gtk_array_free (GtkArray *self,
+ GDestroyNotify element_free_func)
+{
+ guint i;
+
+ if (G_LIKELY (!self->ptr_array))
+ {
+ if (element_free_func)
+ {
+ for (i = 0; i < self->len; i++)
+ element_free_func (self->stack_space[i]);
+ }
+
+ return;
+ }
+
+ g_assert (self->ptr_array);
+
+ if (element_free_func)
+ {
+ for (i = 0; i < self->ptr_array->len; i++)
+ element_free_func (g_ptr_array_index (self->ptr_array, i));
+ }
+
+ g_ptr_array_free (self->ptr_array, TRUE);
+}
+
+
+#endif
#include "gdk/gdk-private.h"
#include "gsk/gskprivate.h"
#include "gsk/gskrendernodeprivate.h"
+#include "gtkarrayimplprivate.h"
#include <locale.h>
double x, y;
GtkWidget *prev;
gboolean seen_ancestor;
- GPtrArray *targets;
+ GtkArray target_array;
+ GtkWidget *stack_targets[16];
int i;
if (old_target == new_target)
widget = _gtk_widget_get_parent (widget);
}
- targets = g_ptr_array_new_full (16, NULL);
+ gtk_array_init (&target_array, (void**)stack_targets, 16);
for (widget = new_target; widget; widget = _gtk_widget_get_parent (widget))
- g_ptr_array_add (targets, widget);
+ gtk_array_add (&target_array, widget);
crossing.direction = GTK_CROSSING_IN;
seen_ancestor = FALSE;
- for (i = (int)targets->len - 1; i >= 0; i--)
+ for (i = (int)target_array.len - 1; i >= 0; i--)
{
- widget = g_ptr_array_index (targets, i);
+ widget = gtk_array_index (&target_array, i);
- if (i < (int)targets->len - 1)
- crossing.new_descendent = g_ptr_array_index (targets, i + 1);
+ if (i < (int)target_array.len - 1)
+ crossing.new_descendent = gtk_array_index (&target_array, i + 1);
else
crossing.new_descendent = NULL;
gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
}
- g_ptr_array_free (targets, TRUE);
+ gtk_array_free (&target_array, NULL);
}
static GtkWidget *
{
gint handled_event = FALSE;
GtkWidget *target = widget;
- GPtrArray *widgets;
+ GtkArray widget_array;
+ GtkWidget *stack_widgets[16];
int i;
- widgets = g_ptr_array_new_full (16, g_object_unref);
- g_ptr_array_add (widgets, g_object_ref (widget));
+ gtk_array_init (&widget_array, (void**)stack_widgets, 16);
+ gtk_array_add (&widget_array, g_object_ref (widget));
for (;;)
{
if (!widget)
break;
- g_ptr_array_add (widgets, g_object_ref (widget));
+ gtk_array_add (&widget_array, g_object_ref (widget));
if (widget == topmost)
break;
}
- i = (int)widgets->len - 1;
+ i = widget_array.len - 1;
for (;;)
{
- widget = g_ptr_array_index (widgets, i);
+ widget = gtk_array_index (&widget_array, i);
if (!_gtk_widget_is_sensitive (widget))
{
i--;
}
- g_ptr_array_free (widgets, TRUE);
+ gtk_array_free (&widget_array, g_object_unref);
return handled_event;
}